package p.sunmes.les.managers;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.badlogic.gdx.Application.ApplicationType;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.assets.loaders.FileHandleResolver;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Pixmap.Format;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFontParameter;
import com.badlogic.gdx.utils.Disposable;
import com.esotericsoftware.spine.SkeletonData;

import p.sunmes.les.util.U;

/**
 * ResourceManager 
 */
public class RM {

	private AssetManager asset = new AssetManager();
	public static String ATLAS_PATH = "PAK/pack.png.atlas";
	public static String RES_DIR = "resources";
	public static FileHandleResolver desktopFileResolver = new FileHandleResolver() {
		@Override
		public FileHandle resolve(String fileName) {
			return getFile(fileName);
		}
	};

	private TextureAtlas atlas;
	private Map<String, AtlasRegion> atlasCache;
	private PolygonSpriteBatch polygonBatch = new PolygonSpriteBatch();

	private FreeTypeFontGenerator generator;
	private BitmapFont font1;
	private BitmapFont font2;
	private Texture maskTexture;
	public static boolean isDesktopAssetLoad = false;
	public static boolean isLogDesktopFilePath = true;

	private List<Disposable> others = new ArrayList<Disposable>();
	private Map<String, SkeletonData> skeletons = new HashMap<String, SkeletonData>();

	public void addDisposableCache(Disposable dispose) {
		if (!others.contains(dispose)) {
			others.add(dispose);
		}
	}

	public static FileHandle getFile(String path) {
		switch (Gdx.app.getType()) {
		case Desktop:
			if (isDesktopAssetLoad) {
				FileHandle fh = new FileHandle(
						String.format("%s/%s", RES_DIR, path));
				if (isLogDesktopFilePath) {
					System.out.println(fh.file().getAbsolutePath());
				}
				return fh;
			}
		default:
			return Gdx.files.internal(path);
		}
	}

	public FreeTypeFontGenerator getGenerator() {
		return generator;
	}

	public Texture getMaskTexture() {
		return maskTexture;
	}

	public RM() {
		generator = new FreeTypeFontGenerator(
				Gdx.files.classpath("font/DroidSansFallback.ttf"));

		FreeTypeFontParameter parameter = new FreeTypeFontParameter();
		parameter.color = Color.WHITE;
		parameter.borderWidth = 1f;
		parameter.size = 24;
		parameter.borderColor = Color.BLACK;
		parameter.minFilter = TextureFilter.Linear;
		parameter.magFilter = TextureFilter.Linear;
		parameter.incremental = true;
		font1 = generator.generateFont(parameter);

		FreeTypeFontParameter parameter2 = new FreeTypeFontParameter();
		parameter2.color = Color.WHITE;
		parameter2.size = 24;
		parameter2.minFilter = TextureFilter.Linear;
		parameter2.magFilter = TextureFilter.Linear;
		parameter2.incremental = true;
		font2 = generator.generateFont(parameter2);

		if (Gdx.app.getType() == ApplicationType.Desktop) {
			asset.dispose();
			asset = new AssetManager(desktopFileResolver);
		}

		//////
		Pixmap pix = new Pixmap(8, 8, Format.RGBA8888);
		pix.setColor(Color.WHITE);
		pix.fill();
		maskTexture = new Texture(pix);
		pix.dispose();

	}

	public PolygonSpriteBatch getPolygonBatch() {
		return polygonBatch;
	}

	public Map<String, SkeletonData> getSkeletons() {
		return skeletons;
	}

	public void loadTextureAtlas() {
		if (!asset.isLoaded(ATLAS_PATH, TextureAtlas.class)) {
			asset.load(ATLAS_PATH, TextureAtlas.class);
		} else {
			System.out.println("Atlas already loaded!");
		}
	}

	public void loadMusics(List<String> musics) {
		for (String str : musics) {
			if (!asset.isLoaded(str, Music.class)) {
				asset.load(str, Music.class);
			}
		}
	}

	public void loadSounds(List<String> sounds) {
		for (String str : sounds) {
			if (!asset.isLoaded(str, Sound.class)) {
				asset.load(str, Sound.class);
			}
		}
	}

	public void listAtlas() {
		checkAtlasIsInit();
		if (atlas != null) {
			for (AtlasRegion ar : atlas.getRegions()) {
				System.out.println(ar.name);
			}
		} else {
			System.out.println("Atlas is not loaded!.");
		}
	}

	public AssetManager Asset() {
		return asset;
	}

	public void checkAtlasIsInit() {
		if (atlas == null) {
			if (asset.isLoaded(ATLAS_PATH)) {
				atlas = asset.get(ATLAS_PATH, TextureAtlas.class);
				atlasCache = new HashMap<String, AtlasRegion>();
				for (AtlasRegion ar : atlas.getRegions()) {
					atlasCache.put(ar.name, ar);
				}
			}
		}
	}

	public TextureRegion getLoad(String name) {
		checkAtlasIsInit();
		if (atlas != null) {
			int p = name.lastIndexOf('.');
			String regionName = name;
			if (p > 0) {
				regionName = name.substring(0, p);
			}
			AtlasRegion region = atlasCache.get(regionName);
			if (region != null) {
				return region;
			}
		}
		if (asset.isLoaded(name)) {
			return new TextureRegion(asset.get(name, Texture.class));
		} else {
			if (!getFile(name).exists()) {
				U.debugErr("没有找到纹理资源[" + name + "]");
				return new TextureRegion(maskTexture);
			}
			asset.load(name, Texture.class);
			asset.finishLoadingAsset(name);
			return new TextureRegion(asset.get(name, Texture.class));
		}
	}

	public BitmapFont getFont1() {
		return font1;
	}

	public BitmapFont getFont2() {
		return font2;
	}

	public void _dispose() {
		maskTexture.dispose();
		asset.dispose();
		polygonBatch.dispose();
		generator.dispose();
		font1.dispose();
		font2.dispose();
	}

	public TextureAtlas getAtlas() {
		return atlas;
	}

	///////////
	private static RM _instance;

	public static RM instance() {
		if (_instance == null) {
			_instance = new RM();
		}
		return _instance;
	}

	public static void dispose() {
		if (_instance != null) {
			_instance._dispose();
			_instance = null;
		}
	}
}
